package org.bing.zion.filter.serializer;

/**
 * Copyright (c) 2007 Greg Whalin
 * All rights reserved. 
 * 
 * Copy from memcached java client.
 */

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ByteBufferInputStream extends InputStream {
	private List<ByteBuffer> list = new ArrayList<ByteBuffer>(2);

	public void add(ByteBuffer buf) throws IOException {
		list.add(buf);
	}

	@Override
	public int available() throws IOException {
		int num = 0;
		for (ByteBuffer b : list) {
			num += b.remaining();
		}
		return num;
	}

	@Override
	public int read() {
		Iterator<ByteBuffer> it = list.iterator();
		while (it.hasNext()) {
			ByteBuffer buf = it.next();
			if (buf.hasRemaining()) {
				return buf.get();
			} else {
				it.remove();
			}
		}
		return -1;
	}

	@Override
	public int read(byte[] buf) {
		return this.read(buf, 0, buf.length);
	}

	@Override
	public int read(byte[] buf, int bufPos, int len) {
		Iterator<ByteBuffer> it = list.iterator();
		while (it.hasNext() && bufPos < len) {
			ByteBuffer bb = it.next();
			int r = bb.remaining();
			if (r > 0) {
				int n = Math.min(r, len - bufPos);
				bb.get(buf, bufPos, n);
				bufPos += n;
				if (!bb.hasRemaining()) {
					it.remove();
				}
			} else {
				it.remove();
			}
		}
		if (bufPos > 0 || (bufPos == 0 && len == 0)) {
			return bufPos;
		} else {
			return -1;
		}
	}

	@Override
	public synchronized void reset() throws IOException {
		list.clear();
	}
}
